package stone926.mods.more_enchantments.util;

import java.util.Optional;
import java.util.Random;

public final class RandomUtil {

  public static boolean isPossible(double chance, Random r) {
    if (chance >= 1) return true;
    else if (chance <= 0) return false;
    else return r.nextDouble() <= chance;
  }

  public static boolean isPossible(int chance, Random r) {
    if (chance <= 0) return false;
    else return r.nextInt(chance) == 0;
  }

  public static <T> Optional<T> runIfPossible(double chance, Random r, FunctionHasReturnValue<T> function) {
    if (isPossible(chance, r)) return Optional.ofNullable(function.run());
    else return Optional.empty();
  }

  public static void runIfPossible(double chance, Random r, FunctionNoReturnValue function) {
    if (isPossible(chance, r)) function.run();
  }

  public static void runIfPossible(int chance, Random r, FunctionNoReturnValue function) {
    if (isPossible(chance, r)) function.run();
  }

  public static void runFunctionsIfPossible(double chance, Random r, FunctionNoReturnValue... functions) {
    for (FunctionNoReturnValue f : functions) if (isPossible(chance, r)) f.run();
  }

  public static int nextInt(int a, Random r) {
    return nextInt(1, a, r);
  }

  public static int nextInt(int a, int b, Random r) {
    if (a == b) return a;
    int small = Math.min(a, b);
    int big = Math.max(a, b);
    return small + r.nextInt(big - small + 1);
  }

  @FunctionalInterface
  public interface FunctionHasReturnValue<T> {

    T run();

  }

  @FunctionalInterface
  public interface FunctionNoReturnValue {

    void run();

  }

}
